﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;

using A = DocumentFormat.OpenXml.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;

namespace component
{
    public partial class DocxBuilderComponent
    {
        //переменная уровня нумерации
        public static int numberingLevel = 0;
        //словарь с идентификаторами нумерации
        public static Dictionary<int, int> NumberingId = new Dictionary<int, int>();
        //идентификатор абстрактного определения в нумерации
        public static int abstrNumId = 0;
        //идентификатор нумерации
        public static int numberId = 0;
        //максимальный идентификатор нумерации
        public static int nemberIdMax = 0;

        public static Dictionary<int, int> levelAndStartValue = new Dictionary<int, int>();

        //удаление лишних знаков
        public static string removeSingles(string formatStr)
        {
            string outStr = "";
            char[] splits = { '\n', '\r', '\t' };
            string[] para = formatStr.Split(splits);
            List<string> list = new List<string>();
            for (int i = 0; i < para.Length; i++)
            {
                if (para[i] != "")
                    list.Add(para[i]);
            }
            foreach (string str in list)
                outStr += str;
            return outStr;
        }

        //просматриваем блочные элементы
        public static List<OpenXmlElement> blockElement(XmlNode blockElementNode)
        {
            //список элементов
            List<OpenXmlElement> listBlockElement = new List<OpenXmlElement>();

            foreach (XmlNode element in blockElementNode)
            {
                if (element.NodeType == XmlNodeType.Element)
                {
                    switch (element.Name)
                    {
                        case "alert":
                            {
                                //добавляем элемент alert
                                listBlockElement.Add(elementAlert(element));
                            }
                            break;
                        case "code":
                            {
                                //добавляем элемент code
                                foreach (OpenXmlElement el in elementCode(element))
                                    listBlockElement.Add(el);
                            }
                            break;
                        case "codeReference":
                            break;
                        case "definitionTable":
                            {
                                //добавляем элемент definitionTable
                                foreach (OpenXmlElement el in elementDefinitionTable(element))
                                    listBlockElement.Add(el);
                            }
                            break;
                        case "mediaLink":
                            {
                                foreach (OpenXmlElement el in elementMediaLink(element))
                                    listBlockElement.Add(el);
                            }
                            break;
                        case "list":
                            {
                                //добавляем элемент list
                                foreach (OpenXmlElement el in elementList(element))
                                    listBlockElement.Add(el);
                                numberId = nemberIdMax;
                                buff = 0;
                                k = 0;
                            }
                            break;
                        case "para":
                            {
                                //добавляем элемент para
                                Paragraph p = new Paragraph();
                                ParagraphProperties pPr = new ParagraphProperties();
                                Justification justification = new Justification() { Val = JustificationValues.Both };
                                pPr.Append(justification);
                                p.Append(pPr);
                                List<OpenXmlElement> para = elementPara(element);
                                foreach (OpenXmlElement el in para)
                                    p.Append(el);
                                listBlockElement.Add(p);
                            }
                            break;
                        case "quote":
                            {
                                //добавляем элемент quote
                                listBlockElement.Add(elementQuote(element));
                            }
                            break;
                        case "table":
                            {
                                //добавляем элемент table
                                listBlockElement.Add(elementTable(element));
                            }
                            break;
                        case "title":
                            {
                                //добавляем элемент title
                                Paragraph p = new Paragraph();
                                ParagraphProperties pPr = new ParagraphProperties();
                                ParagraphStyleId pStyle = new ParagraphStyleId() { Val = "Title" };
                                pPr.Append(pStyle);
                                p.Append(pPr);
                                List<OpenXmlElement> para = elementPara(element);
                                foreach (OpenXmlElement el in para)
                                    p.Append(el);
                                listBlockElement.Add(p);
                            }
                            break;
                        case "content":
                            {
                                //добавляем элемент content
                                foreach (OpenXmlElement el in blockElement(element))
                                    listBlockElement.Add(el);
                            }
                            break;
                    }
                }
            }
            return listBlockElement;
        }

        public static List<OpenXmlElement> elementPara(XmlNode node)
        {
            List<OpenXmlElement> listRun = new List<OpenXmlElement>();
            if (node.HasChildNodes)
            {
                foreach (XmlNode element in node)
                {
                    if (element.NodeType == XmlNodeType.Text)
                    {
                        Run r = new Run();
                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                        text.Text = removeSingles(element.Value);
                        r.Append(text);
                        listRun.Add(r);
                    }
                    if (element.NodeType == XmlNodeType.Element)
                    {
                        foreach (OpenXmlElement el in inlineElement(element))
                            listRun.Add(el);
                    }
                }
            }
            return listRun;
        }



        public static int buff = 0, k = 0;

        public static List<OpenXmlElement> elementList(XmlNode node)
        {
            levelAndStartValue[buff] = 1;
            numberId++;
            NumberingId[k] = numberId;
            if (numberId > nemberIdMax)
                nemberIdMax = numberId;

            List<OpenXmlElement> returnList = new List<OpenXmlElement>();
            //список для содержания не блочних элементов (простой текст или инлайновых элементов)
            List<OpenXmlElement> listNotBlock = new List<OpenXmlElement>();

            if (node.Attributes.Count != 0)
            {
                if (node.Attributes["class"].Value == "bullet")
                {
                    numbering.Append(generateNumbering.generateBullet(abstrNumId, levelAndStartValue));
                    abstrNumId++;
                }

                if (node.Attributes["class"].Value == "ordered")
                {
                    numbering.Append(generateNumbering.generateOrdered(abstrNumId, levelAndStartValue));
                    abstrNumId++;
                }
                if (node.Attributes["class"].Value == "nobullet")
                {
                    numbering.Append(generateNumbering.generateNoBullet(abstrNumId, levelAndStartValue));
                    abstrNumId++;
                }
            }

            if (node.HasChildNodes)
            {
                foreach (XmlNode element in node)
                {
                    if (element.NodeType == XmlNodeType.Element && element.Name == "listItem")
                    {
                        foreach (XmlNode element2 in element)
                        {
                            if (element2.NodeType == XmlNodeType.Element)
                            {
                                switch (element2.Name)
                                {
                                    case "alert":
                                        {
                                            Console.WriteLine("incorrectly display a tag \"alert\" in the tag \"list\"");
                                            returnList.Add(elementAlert(element2));
                                        }
                                        break;
                                    case "code":
                                        {
                                            Console.WriteLine("incorrectly display a tag \"code\" in the tag \"list\"");
                                            foreach (OpenXmlElement el in elementCode(element2))
                                                returnList.Add(el);
                                        }
                                        break;
                                    case "codeReference":
                                        break;
                                    case "definitionTable":
                                        break;
                                    case "introduction":
                                        break;
                                    case "list":
                                        {
                                            //увеличиваем уровень нумерации
                                            numberingLevel++;
                                            NumberingId[k] = numberId;
                                            k++;
                                            numberId = nemberIdMax;
                                            levelAndStartValue[buff]--;
                                            buff++;
                                            foreach (OpenXmlElement el in elementList(element2))
                                                returnList.Add(el);
                                            k--;
                                            levelAndStartValue[buff] = 1;
                                            buff--;
                                            levelAndStartValue[buff]++;
                                            numberId--;
                                            //уменьшаем уровень нумерации
                                            numberingLevel--;
                                        }
                                        break;
                                    case "para":
                                        {
                                            Paragraph p = new Paragraph();
                                            ParagraphProperties pPr = new ParagraphProperties(
                                                                          new NumberingProperties(
                                                                          new NumberingLevelReference() { Val = numberingLevel },
                                                                          new NumberingId() { Val = NumberingId[k] }));
                                            p.Append(pPr);
                                            foreach (OpenXmlElement el in elementPara(element2))
                                                p.Append(el);
                                            levelAndStartValue[buff]++;
                                            returnList.Add(p);
                                        }
                                        break;
                                    case "quote":
                                        {
                                            Console.WriteLine("incorrectly display a tag \"quote\" in the tag \"list\"");
                                            returnList.Add(elementQuote(element2));
                                        }
                                        break;
                                    case "table":
                                        {
                                            Console.WriteLine("incorrectly display a tag \"table\" in the tag \"list\"");
                                            returnList.Add(elementTable(element2));
                                        }
                                        break;
                                    case "content":
                                        {
                                            Console.WriteLine("tag \"content\" can not be contained in the tag \"list\"");
                                        }
                                        break;
                                    default:
                                        {
                                            //если не блочный элемент, ищем в инлайновых элементах
                                            foreach (OpenXmlElement el in inlineElement(element2))
                                                listNotBlock.Add(el);
                                        }
                                        break;
                                }
                            }

                            if (element2.NodeType == XmlNodeType.Text)
                            {
                                string txt = removeSingles(element2.Value);
                                if (txt != "")
                                {
                                    Run r = new Run();
                                    Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                    text.Text = txt;
                                    r.Append(text);
                                    listNotBlock.Add(r);
                                }
                            }
                        }

                        if (listNotBlock.Count > 0)
                        {
                            Paragraph p = new Paragraph();
                            ParagraphProperties pPr = new ParagraphProperties(
                                                                          new NumberingProperties(
                                                                          new NumberingLevelReference() { Val = numberingLevel },
                                                                          new NumberingId() { Val = NumberingId[k] }));
                            p.Append(pPr);
                            foreach (OpenXmlElement r in listNotBlock)
                                p.Append(r);
                            levelAndStartValue[buff]++;
                            returnList.Add(p);
                            listNotBlock.Clear();
                        }
                    }
                }
            }

            return returnList;
        }

        public static Table elementTable(XmlNode node)
        {
            List<OpenXmlElement> listRun = new List<OpenXmlElement>();

            Table table = new Table();

            TableProperties tblPr = new TableProperties();
            TableStyle tblStyle = new TableStyle() { Val = "Table" };
            tblPr.Append(tblStyle);
            table.Append(tblPr);

            if (node.HasChildNodes)
            {
                foreach (XmlNode element in node)
                {
                    //if(element.NodeType == XmlNodeType.Element && (element.Name == "tableHeader"))

                    if (element.NodeType == XmlNodeType.Element && (element.Name == "row"))
                    {
                        TableRow tr = new TableRow();

                        foreach (XmlNode element2 in element)
                        {
                            if (element2.NodeType == XmlNodeType.Element && element2.Name == "entry")
                            {
                                TableCell tc = new TableCell();

                                foreach (XmlNode element3 in element2)
                                {
                                    if (element3.NodeType == XmlNodeType.Element)
                                    {
                                        switch (element3.Name)
                                        {
                                            case "alert":
                                                {
                                                    tc.Append(elementAlert(element3));
                                                }
                                                break;
                                            case "code":
                                                {
                                                    foreach (OpenXmlElement el in elementCode(element3))
                                                        tc.Append(el);
                                                }
                                                break;
                                            case "codeReference":
                                                break;
                                            case "definitionTable":
                                                {
                                                    foreach (OpenXmlElement el in elementDefinitionTable(element3))
                                                        tc.Append(el);
                                                }
                                                break;
                                            case "introduction":
                                                break;
                                            case "list":
                                                {
                                                    foreach (OpenXmlElement el in elementList(element3))
                                                        tc.Append(el);
                                                    numberId = nemberIdMax;
                                                    buff = 0;
                                                    k = 0;
                                                }
                                                break;
                                            case "para":
                                                {
                                                    Paragraph p = new Paragraph();
                                                    ParagraphProperties paragraphProperties20 = new ParagraphProperties();
                                                    ConditionalFormatStyle conditionalFormatStyle24 = new ConditionalFormatStyle() { Val = "000000000000", FirstRow = false, LastRow = false, FirstColumn = false, LastColumn = false, OddVerticalBand = false, EvenVerticalBand = false, OddHorizontalBand = false, EvenHorizontalBand = false, FirstRowFirstColumn = false, FirstRowLastColumn = false, LastRowFirstColumn = false, LastRowLastColumn = false };
                                                    paragraphProperties20.Append(conditionalFormatStyle24);
                                                    p.Append(paragraphProperties20);

                                                    List<OpenXmlElement> para = elementPara(element3);
                                                    foreach (OpenXmlElement el in para)
                                                        p.Append(el);
                                                    tc.Append(p);
                                                }
                                                break;
                                            case "quote":
                                                {
                                                    tc.Append(elementQuote(element3));
                                                }
                                                break;
                                            case "table":
                                                {
                                                    tc.Append(elementTable(element3));
                                                }
                                                break;
                                            case "content":
                                                {
                                                    Console.WriteLine("tag \"content\" can not be contained in the tag \"table\"");
                                                }
                                                break;
                                            default:
                                                {
                                                    foreach (OpenXmlElement el in inlineElement(element3))
                                                        listRun.Add(el);
                                                }
                                                break;
                                        }
                                    }

                                    if (element3.NodeType == XmlNodeType.Text)
                                    {
                                        string txt = removeSingles(element3.Value);
                                        if (txt != "")
                                        {
                                            Run r = new Run();
                                            Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                            text.Text = txt;
                                            r.Append(text);
                                            listRun.Add(r);
                                        }
                                    }
                                }
                                if (listRun.Count > 0)
                                {
                                    Paragraph p = new Paragraph();
                                    foreach (OpenXmlElement r in listRun)
                                        p.Append(r);
                                    tc.Append(p);
                                    listRun.Clear();
                                }

                                tr.Append(tc);
                            }
                        }
                        table.Append(tr);
                    }
                }
            }
            return table;
        }

        public static Table elementAlert(XmlNode alertNode)
        {
            List<OpenXmlElement> listRun = new List<OpenXmlElement>();

            Table table = new Table();

            TableProperties tblPr = new TableProperties();
            TableStyle tblStyle = new TableStyle() { Val = "Alert" };
            tblPr.Append(tblStyle);
            table.Append(tblPr);

            TableRow tr = new TableRow();
            TableCell tc = new TableCell();

            foreach (XmlNode element in alertNode)
            {
                if (element.NodeType == XmlNodeType.Element)
                {
                    switch (element.Name)
                    {
                        case "alert":
                            {
                                tc.Append(elementAlert(element));
                            }
                            break;
                        case "code":
                            {
                                foreach (OpenXmlElement el in elementCode(element))
                                    tc.Append(el);
                            }
                            break;
                        case "codeReference":
                            break;
                        case "definitionTable":
                            {
                                foreach (OpenXmlElement el in elementDefinitionTable(element))
                                    tc.Append(el);
                            }
                            break;
                        case "introduction":
                            break;
                        case "list":
                            {
                                foreach (OpenXmlElement el in elementList(element))
                                    tc.Append(el);
                                numberId = nemberIdMax;
                                buff = 0;
                                k = 0;
                            }
                            break;
                        case "para":
                            {
                                Paragraph p = new Paragraph();
                                foreach (OpenXmlElement el in elementPara(element))
                                    p.Append(el);
                                tc.Append(p);
                            }
                            break;
                        case "quote":
                            {
                                tc.Append(elementQuote(element));
                            }
                            break;
                        case "table":
                            {
                                tc.Append(elementTable(element));
                            }
                            break;
                        case "content":
                            {
                                tc.Append(elementAlert(element));
                            }
                            break;
                        default:
                            {
                                foreach (OpenXmlElement el in inlineElement(element))
                                    listRun.Add(el);
                            }
                            break;
                    }
                }

                if (element.NodeType == XmlNodeType.Text)
                {
                    string txt = removeSingles(element.Value);
                    if (txt != "")
                    {
                        Run r = new Run();
                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                        text.Text = txt;
                        r.Append(text);
                        listRun.Add(r);
                    }
                }
            }

            if (listRun.Count > 0)
            {
                Paragraph p = new Paragraph();
                ParagraphProperties pPr = new ParagraphProperties();
                ParagraphStyleId pStyleId = new ParagraphStyleId() { Val = "Alert" };
                pPr.Append(pStyleId);
                p.Append(pPr);
                foreach (Run r in listRun)
                    p.Append(r);
                tc.Append(p);
                listRun.Clear();
            }

            //т.к. в тэге tc обязательно должен находится элемент p, добаляем его, если его нет
            bool hasPara = false;
            OpenXmlElementList boofList = tc.ChildElements;
            foreach (OpenXmlElement el in boofList)
            {
                if (el.LocalName == "p")
                {
                    hasPara = true;
                    break;
                }
            }
            if (!hasPara)
            {
                Paragraph boofPara = new Paragraph();
                tc.Append(boofPara);
            }

            tr.Append(tc);
            table.Append(tr);

            return table;
        }

        public static Table elementQuote(XmlNode node)
        {
            List<OpenXmlElement> listRun = new List<OpenXmlElement>();

            Table table = new Table();

            TableProperties tblPr = new TableProperties();
            TableStyle tblStyle = new TableStyle() { Val = "Quote" };

            tblPr.Append(tblStyle);
            table.Append(tblPr);

            TableRow tr = new TableRow();
            TableCell tc = new TableCell();

            foreach (XmlNode element in node)
            {
                if (element.NodeType == XmlNodeType.Element)
                {
                    switch (element.Name)
                    {
                        case "alert":
                            {
                                tc.Append(elementAlert(element));
                            }
                            break;
                        case "code":
                            {
                                foreach (OpenXmlElement el in elementCode(element))
                                    tc.Append(el);
                            }
                            break;
                        case "codeReference":
                            break;
                        case "definitionTable":
                            {
                                foreach (OpenXmlElement el in elementDefinitionTable(element))
                                    tc.Append(el);
                            }
                            break;
                        case "introduction":
                            break;
                        case "list":
                            {
                                foreach (OpenXmlElement el in elementList(element))
                                    tc.Append(el);
                                numberId = nemberIdMax;
                                buff = 0;
                                k = 0;
                            }
                            break;
                        case "para":
                            {
                                Paragraph p = new Paragraph();
                                foreach (OpenXmlElement el in elementPara(element))
                                    p.Append(el);
                                tc.Append(p);
                            }
                            break;
                        case "quote":
                            {
                                tc.Append(elementQuote(element));
                            }
                            break;
                        case "table":
                            {
                                tc.Append(elementTable(element));
                            }
                            break;
                        case "content":
                            {
                                tc.Append(elementQuote(element));
                            }
                            break;
                        default:
                            {
                                foreach (Run el in inlineElement(element))
                                    listRun.Add(el);
                            }
                            break;
                    }
                }

                if (element.NodeType == XmlNodeType.Text)
                {
                    string txt = removeSingles(element.Value);
                    if (txt != "")
                    {
                        Run r = new Run();
                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                        text.Text = txt;
                        r.Append(text);
                        listRun.Add(r);
                    }
                }
            }
            if (listRun.Count > 0)
            {
                Paragraph p = new Paragraph();
                ParagraphProperties pPr = new ParagraphProperties();
                ParagraphStyleId pStyleId = new ParagraphStyleId() { Val = "Quote" };
                pPr.Append(pStyleId);
                p.Append(pPr);
                foreach (Run r in listRun)
                    p.Append(r);
                tc.Append(p);
                listRun.Clear();
            }

            //т.к. в тэге tc обязательно должен находится элемент p, добаляем его, если его нет
            bool hasPara = false;
            OpenXmlElementList boofList = tc.ChildElements;
            foreach (OpenXmlElement el in boofList)
            {
                if (el.LocalName == "p")
                {
                    hasPara = true;
                    break;
                }
            }
            if (!hasPara)
            {
                Paragraph boofPara = new Paragraph();
                tc.Append(boofPara);
            }

            tr.Append(tc);
            table.Append(tr);
            return table;
        }

        public static List<OpenXmlElement> elementCode(XmlNode codeNode)
        {
            List<OpenXmlElement> listCode = new List<OpenXmlElement>();

            Table table = new Table();

            TableProperties tblPr = new TableProperties();
            TableStyle tblStyle = new TableStyle() { Val = "Code" };

            tblPr.Append(tblStyle);
            table.Append(tblPr);

            TableRow tr = new TableRow();
            TableCell tc = new TableCell();


            if (codeNode.Attributes.Count != 0)
            {
                foreach (XmlAttribute attribute in codeNode.Attributes)
                {
                    if (attribute.Name == "title")
                    {
                        Paragraph p = new Paragraph();
                        ParagraphProperties pPr = new ParagraphProperties();
                        ParagraphStyleId pStyleId = new ParagraphStyleId() { Val = "CodeTitle" };
                        pPr.Append(pStyleId);
                        p.Append(pPr);
                        p.Append(new Run(new Text(attribute.InnerText)));
                        listCode.Add(p);
                    }

                    if (attribute.Name == "source")
                    {
                        try
                        {
                            StreamReader sr = File.OpenText(basePath + attribute.InnerText);
                            string data = sr.ReadToEnd();

                            char[] splits = { '\n', '\r', '\t' };
                            string[] para = data.Split(splits);

                            Paragraph p = new Paragraph();

                            bool flag = false;
                            foreach (string str in para)
                            {
                                if (!String.IsNullOrEmpty(str))
                                {
                                    Run r = new Run();
                                    if (flag)
                                    {
                                        Break br = new Break();
                                        r.Append(br);
                                    }
                                    Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                    text.Text = str;
                                    r.Append(text);
                                    p.Append(r);
                                    flag = true;
                                }
                            }
                            tc.Append(p);

                            sr.Close();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("The process failed: {0}", e.ToString());
                        }
                    }
                }
            }

            if (codeNode.HasChildNodes)
            {
                foreach (XmlNode element in codeNode)
                {
                    if (element.NodeType == XmlNodeType.Text)
                    {
                        char[] splits = { '\n', '\r', '\t' };
                        string[] para = element.Value.Split(splits);

                        Paragraph p = new Paragraph();

                        bool flag = false;
                        foreach (string str in para)
                        {
                            if (!String.IsNullOrEmpty(str))
                            {
                                Run r = new Run();
                                if (flag)
                                {
                                    Break br = new Break();
                                    r.Append(br);
                                }
                                Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                text.Text = str;
                                r.Append(text);
                                p.Append(r);
                                flag = true;
                            }
                        }
                        tc.Append(p);
                    }
                }
            }

            //т.к. в тэге tc обязательно должен находится элемент p, добаляем его, если его нет
            bool hasPara = false;
            OpenXmlElementList boofList = tc.ChildElements;
            foreach (OpenXmlElement el in boofList)
            {
                if (el.LocalName == "p")
                {
                    hasPara = true;
                    break;
                }
            }
            if (!hasPara)
            {
                Paragraph boofPara = new Paragraph();
                tc.Append(boofPara);
            }

            tr.Append(tc);
            table.Append(tr);
            listCode.Add(table);

            return listCode;
        }

        public static List<OpenXmlElement> elementDefinitionTable(XmlNode node)
        {
            List<OpenXmlElement> listDefinitionTable = new List<OpenXmlElement>();

            if (node.HasChildNodes)
            {
                foreach (XmlNode element in node)
                {
                    if (element.NodeType == XmlNodeType.Element && element.Name == "definedTerm")
                    {
                        List<OpenXmlElement> listRun = new List<OpenXmlElement>();
                        foreach (XmlNode element2 in element)
                        {
                            if (element2.NodeType == XmlNodeType.Text)
                            {
                                Run r = new Run();
                                RunProperties rPr = new RunProperties();
                                RunStyle rStyle = new RunStyle() { Val = "ae" };
                                rPr.Append(rStyle);
                                r.Append(rPr);

                                Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                text.Text = removeSingles(element2.Value);
                                r.Append(text);
                                listRun.Add(r);
                            }

                            if (element2.NodeType == XmlNodeType.Element)
                            {
                                foreach (OpenXmlElement r in inlineElement(element2))
                                    listRun.Add(r);
                            }
                        }

                        Paragraph p = new Paragraph();
                        foreach (OpenXmlElement r in listRun)
                            p.Append(r);
                        listDefinitionTable.Add(p);
                    }

                    if (element.NodeType == XmlNodeType.Element && element.Name == "definition")
                    {
                        List<OpenXmlElement> listRun = new List<OpenXmlElement>();

                        foreach (XmlNode element2 in element)
                        {
                            if (element2.NodeType == XmlNodeType.Element)
                            {
                                switch (element2.Name)
                                {

                                    case "alert":
                                        {
                                            listDefinitionTable.Add(elementAlert(element2));
                                        }
                                        break;
                                    case "code":
                                        {
                                            foreach (OpenXmlElement el in elementCode(element2))
                                                listDefinitionTable.Add(el);
                                        }
                                        break;
                                    case "codeReference":
                                        break;
                                    case "definitionTable":
                                        break;
                                    case "introduction":
                                        break;
                                    case "list":
                                        {
                                            foreach (OpenXmlElement el in elementList(element2))
                                                listDefinitionTable.Add(el);
                                            numberId = nemberIdMax;
                                            buff = 0;
                                            k = 0;
                                        }
                                        break;
                                    case "para":
                                        {
                                            Paragraph p = new Paragraph();
                                            foreach (OpenXmlElement el in elementPara(element2))
                                                p.Append(el);
                                            listDefinitionTable.Add(p);
                                        }
                                        break;
                                    case "quote":
                                        {
                                            listDefinitionTable.Add(elementQuote(element2));
                                        }
                                        break;
                                    case "table":
                                        {
                                            listDefinitionTable.Add(elementTable(element2));
                                        }
                                        break;
                                    case "content":
                                        {

                                        }
                                        break;
                                    default:
                                        {
                                            List<OpenXmlElement> newListInlineElement = inlineElement(element2);
                                            foreach (OpenXmlElement el in newListInlineElement)
                                                listRun.Add(el);
                                        }
                                        break;
                                }
                            }

                            if (element2.NodeType == XmlNodeType.Text)
                            {
                                string txt = removeSingles(element2.Value);
                                if (txt != "")
                                {
                                    Run r = new Run();
                                    Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                    text.Text = txt;
                                    r.Append(text);
                                    listRun.Add(r);
                                }
                            }
                        }

                        if (listRun.Count > 0)
                        {
                            Paragraph p = new Paragraph();
                            foreach (OpenXmlElement r in listRun)
                                p.Append(r);
                            listDefinitionTable.Add(p);
                            listRun.Clear();
                        }
                    }
                }
            }
            return listDefinitionTable;
        }

        public static List<OpenXmlElement> elementMediaLink(XmlNode node)
        {
            List<OpenXmlElement> returnList = new List<OpenXmlElement>();
            bool afterFlag = false;
            Paragraph pAfter = new Paragraph();

            if (node.HasChildNodes)
            {
                foreach (XmlNode element in node)
                {
                    if (element.NodeType == XmlNodeType.Element)
                    {
                        switch (element.Name)
                        {
                            case "image":
                                {
                                    Paragraph p = new Paragraph();
                                    p.Append(getDrawing(element));
                                    returnList.Add(p);
                                    if (afterFlag)
                                    {
                                        returnList.Add(pAfter);
                                        afterFlag = false;
                                    }
                                }
                                break;

                            case "caption":
                                {
                                    Paragraph p = new Paragraph();
                                    //ParagraphProperties pPr = new ParagraphProperties();
                                    //Justification justification = new Justification() { Val = JustificationValues.Both };
                                    //pPr.Append(justification);
                                    //p.Append(pPr);
                                    List<OpenXmlElement> list = elementPara(element);
                                    foreach (OpenXmlElement el in list)
                                        p.Append(el);
                                    if (element.Attributes.Count != 0)
                                    {
                                        foreach (XmlAttribute attr in element.Attributes)
                                        {
                                            if (attr.Name == "placement" && attr.InnerText == "after")
                                            {
                                                afterFlag = true;
                                                pAfter = p;
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                    returnList.Add(p);
                                }
                                break;
                        }
                    }
                }
            }

            return returnList;
        }

        public static Run getDrawing(XmlNode image)
        {
            Run drawRun = new Run();
            if (image.Attributes.Count != 0)
            {
                string mediaId = image.Attributes["xlink:href"].InnerText;

                foreach (string id in mediaIdAndImagePartName.Keys)
                {
                    if (mediaId == id)
                    {
                        long[] heightAndWidth = mediaIdAndHeightWidth[id];
                        var el =
                     new Drawing(
                         new DW.Inline(
                             new DW.Extent() { Cx = heightAndWidth[1] * 914400 / 96, Cy = heightAndWidth[0] * 914400 / 96 },
                             new DW.EffectExtent()
                             {
                                 LeftEdge = 0L,
                                 TopEdge = 0L,
                                 RightEdge = 0L,
                                 BottomEdge = 0L
                             },
                             new DW.DocProperties()
                             {
                                 Id = (UInt32Value)1U,
                                 Name = "Picture 1"
                             },
                             new DW.NonVisualGraphicFrameDrawingProperties(
                                 new A.GraphicFrameLocks() { NoChangeAspect = true }),
                             new A.Graphic(
                                 new A.GraphicData(
                                     new PIC.Picture(
                                         new PIC.NonVisualPictureProperties(
                                             new PIC.NonVisualDrawingProperties()
                                             {
                                                 Id = (UInt32Value)0U,
                                                 Name = "New Bitmap Image.jpg"
                                             },
                                             new PIC.NonVisualPictureDrawingProperties()),
                                         new PIC.BlipFill(
                                             new A.Blip(
                                                 new A.BlipExtensionList(
                                                     new A.BlipExtension()
                                                     {
                                                         Uri =
                                                           "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                     })
                                             )
                                             {

                                                 Embed = mediaIdAndImagePartId[id],
                                                 CompressionState =
                                                 A.BlipCompressionValues.Print
                                             },
                                             new A.Stretch(
                                                 new A.FillRectangle())),
                                         new PIC.ShapeProperties(
                                             new A.Transform2D(
                                                 new A.Offset() { X = 0L, Y = 0L },
                                                 new A.Extents() { Cx = heightAndWidth[1] * 914400 / 96, Cy = heightAndWidth[0] * 914400 / 96 }),
                                             new A.PresetGeometry(
                                                 new A.AdjustValueList()
                                             ) { Preset = A.ShapeTypeValues.Rectangle }))
                                 ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
                         )
                         {
                             DistanceFromTop = (UInt32Value)0U,
                             DistanceFromBottom = (UInt32Value)0U,
                             DistanceFromLeft = (UInt32Value)0U,
                             DistanceFromRight = (UInt32Value)0U,
                             EditId = "50D07946"
                         });
                        drawRun = new Run(el);
                    }
                }
            }

            return drawRun;
        }
    }
}
